package com.pshcp.api;

import cn.hutool.core.date.DateUtil;
import com.external.dahantc.DahantcService;
import com.external.dahantc.domain.DahantcRes;
import com.external.hospital.ap.UserApManager;
import com.external.service.ScheduleService;
import com.external.service.job.DeptSyncJob;
import com.external.service.job.DoctorSyncJob;
import com.external.service.job.NewsSyncJob;
import com.external.service.job.SchedulingSyncJob;
import com.framework.base.ResultBuilder;
import com.framework.exception.BizException;
import com.framework.logaop.Log;
import com.framework.logaop.LogSourceEnum;
import com.framework.logaop.LogTypeEnum;
import com.framework.thread.ReqComDTO;
import com.framework.thread.ReqComTool;
import com.framework.tool.CommonTool;
import com.framework.util.JwtUtil;
import com.framework.util.SystemUtil;
import com.pshcp.ao.common.CommonAO;
import com.pshcp.ao.common.DeptDescDocRelAO;
import com.pshcp.ao.common.ExternalLogListAO;
import com.pshcp.ao.common.TestDeptDescAO;
import com.pshcp.ao.common.TestDocUpdateAO;
import com.pshcp.ao.common.TestTokenAO;
import com.pshcp.common.enums.CommonStatusEnum;
import com.pshcp.domain.model.DeptDesc;
import com.pshcp.domain.model.DeptDoctorDescRel;
import com.pshcp.domain.model.Doctor;
import com.pshcp.domain.model.ExternalLog;
import com.pshcp.domain.model.Patient;
import com.pshcp.domain.model.PatientUser;
import com.pshcp.domain.model.Session;
import com.pshcp.domain.model.SmsCaptcha;
import com.pshcp.service.*;
import com.pshcp.tool.SessionTool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * @Description: TODO
 * @Author: xiaoche
 * @Date: 2022/11/2 22:35
 */
@Api(tags = {"仅仅开发期间使用接口"})
@Slf4j
@RestController
@RequestMapping("/api/test")
public class TestAPI {

    @Autowired
    private SmsCaptchaService smsCaptchaService;
    @Resource
    private ScheduleService scheduleService;

    @Autowired
    private PatientUserService patientUserService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private DoctorService doctorService;

    @Autowired
    private SessionService sessionService;

    @Autowired
    private DahantcService dahantcService;

    @Autowired
    private UserApManager userApManager;
    @Autowired
    private PatientService patientService;

    @Autowired
    private ExternalLogService externalLogService;

    @Autowired
    private DeptDescService deptDescService;

    @Autowired
    private DeptDoctorDescRelService deptDoctorDescRelService;

    @Autowired
    private FileAPI fileAPI;
    @Autowired
    private PatientReportService patientReportService;

    @PostMapping(value = {"/queryReportList"})
    public void queryReportList(){
        patientReportService.queryReportList();
    }

    @ApiOperation("（仅仅开发期间使用）生成患者token")
    @PostMapping(value = {"/getPatientToken"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（仅仅开发期间使用）生成患者token")
    public Object getPatientToken(@RequestBody TestTokenAO testTokenAO) throws BizException {
        CommonTool.checkString(testTokenAO.getPhone(), "90000006");
        PatientUser patientUserByPhone = patientUserService.getPatientUserByPhone(testTokenAO.getPhone());
        Session session = SessionTool.buildLonginSession(jwtUtil, 1, patientUserByPhone.getId());
        sessionService.insert(session);
        return ResultBuilder.success(session.getToken());
    }

    @ApiOperation("（仅仅开发期间使用）生成医生token")
    @PostMapping(value = {"/getDoctorToken"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（仅仅开发期间使用）生成医生token")
    public Object getDoctorToken(@RequestBody TestTokenAO testTokenAO) throws BizException {
        CommonTool.checkString(testTokenAO.getPhone(), "90000006");
        Doctor doctorByPhone = doctorService.getDoctorByPhone(testTokenAO.getPhone());
        Session session = SessionTool.buildLonginSession(jwtUtil, 0, doctorByPhone.getId());
        sessionService.insert(session);
        return ResultBuilder.success(session.getToken());
    }

    @ApiOperation("（仅仅开发期间使用）获取短信验证码")
    @PostMapping(value = {"/getSmsCaptcha"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（仅仅开发期间使用）获取短信验证码")
    public Object getSmsCaptcha(@RequestBody CommonAO commonAO) throws BizException {
        log.info("（仅仅开发期间使用）获取短信验证码id:{}", ReqComTool.getReqBody());
        CommonTool.checkObj(commonAO.getId(), "90000006");
        SmsCaptcha smsCaptcha = smsCaptchaService.findById(commonAO.getId());
        return ResultBuilder.success(smsCaptcha);
    }

    @ApiOperation("（仅仅开发期间使用）获取登录信息")
    @PostMapping(value = {"/getReqComDTO"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（仅仅开发期间使用）获取登录信息")
    public Object getReqComDTO() throws BizException {
        ReqComDTO reqComDTO = ReqComTool.getReqComDTO();
        return ResultBuilder.success(reqComDTO);
    }

    @ApiOperation("同步医生数据")
    @GetMapping("syncDoctorData")
    public Object syncDoctorData() {
        //10秒后执行任务
        Date execTime = DateUtil.date(LocalDateTime.now().plusSeconds(10L));
        scheduleService.scheduleFixTimeJob(DoctorSyncJob.class, execTime, null);
        return ResultBuilder.success("10s后自动运行");
    }

    @ApiOperation("同步科室数据")
    @GetMapping("syncDeptData")
    public Object syncDeptData() {
        //10秒后执行任务
        Date execTime = DateUtil.date(LocalDateTime.now().plusSeconds(10L));
        scheduleService.scheduleFixTimeJob(DeptSyncJob.class, execTime, null);
        return ResultBuilder.success("10s后自动运行");
    }


    @ApiOperation("同步排班数据")
    @GetMapping("syncSchedulingData")
    public Object syncSchedulingData() {
        //10秒后执行任务
        Date execTime = DateUtil.date(LocalDateTime.now().plusSeconds(10L));
        scheduleService.scheduleFixTimeJob(SchedulingSyncJob.class, execTime, null);
        return ResultBuilder.success("10s后自动运行");
    }


    @ApiOperation("同步医院文章")
    @GetMapping("syncNews")
    public Object syncNews() {
        //10秒后执行任务
        Date execTime = DateUtil.date(LocalDateTime.now().plusSeconds(10L));
        scheduleService.scheduleFixTimeJob(NewsSyncJob.class, execTime, null);
        return ResultBuilder.success("10s后自动运行");
    }

    @ApiOperation("（测试）发送短信")
    @PostMapping(value = {"/sendSms"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（仅仅开发期间使用）发送短信")
    public Object sendSms(@RequestBody TestTokenAO testTokenAO) {
        DahantcRes dahantcRes = dahantcService.sendSms(1, SystemUtil.getUUID(), testTokenAO.getPhone(), "567543");
        return dahantcRes;
    }

    @ApiOperation("（同步）就诊人")
    @PostMapping(value = {"/savePatientInquirer"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（同步）就诊人")
    public Object savePatientInquirer(@RequestBody CommonAO commonAO) {
        Patient patient = patientService.findById(commonAO.getId());
        if (patient == null) {
            return ResultBuilder.success("失败");
        }
        userApManager.savePatientInquirer(patient);
        return ResultBuilder.success("成功");
    }

    @ApiOperation("（同步）患者")
    @PostMapping(value = {"/savePatient"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（同步）患者")
    public Object savePatient(@RequestBody CommonAO commonAO) {
        PatientUser patientUser = patientUserService.findById(commonAO.getId());
        if (patientUser == null) {
            return ResultBuilder.success("失败");
        }
        userApManager.savePatient(patientUser);
        return ResultBuilder.success("成功");
    }

    @ApiOperation("（同步）医生")
    @PostMapping(value = {"/saveDoctor"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（同步）医生")
    public Object saveDoctor(@RequestBody CommonAO commonAO) {
        Doctor doctor = doctorService.findById(commonAO.getId());
        if (doctor == null) {
            return ResultBuilder.success("失败");
        }
        userApManager.saveDoctor(doctor);
        return ResultBuilder.success("成功");
    }

    @ApiOperation("三方服务：调用日志")
    @PostMapping(value = {"/getExternalLogList"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "三方服务：调用日志")
    public Object getExternalLogList(@RequestBody ExternalLogListAO externalLogListAO) {
        List<ExternalLog> list = externalLogService.getExternalLogList(externalLogListAO.getPshcpTraceId());
        return ResultBuilder.success(list);
    }

    @ApiOperation("（测试数据）：增加科室介绍")
    @PostMapping(value = {"/saveDeptDesc"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（测试数据）：增加科室介绍")
    public Object saveDeptDesc(@Valid @RequestBody TestDeptDescAO testDeptDescAO) throws BizException {
        List<DeptDesc> deptDescs = deptDescService.findByDeptName(testDeptDescAO.getDeptName());
        if(!CollectionUtils.isEmpty(deptDescs)){
            throw new BizException("90000002","科室介绍-科室名称已存在~");
        }
        deptDescService.insert(CommonTool.copyProperties(testDeptDescAO, DeptDesc.class));
        return ResultBuilder.success();
    }

    @ApiOperation("（测试数据）：修改科室介绍")
    @PostMapping(value = {"/updateDeptDesc"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（测试数据）：修改科室介绍")
    public Object updateDeptDesc(@Valid @RequestBody TestDeptDescAO testDeptDescAO) throws BizException {
        List<DeptDesc> deptDescs = deptDescService.findByDeptName(testDeptDescAO.getDeptName());
        if(CollectionUtils.isEmpty(deptDescs)){
            throw new BizException("90000002","科室介绍-科室名称不存在，不允许修改~");
        }
        DeptDesc deptDesc = CommonTool.copyProperties(testDeptDescAO, DeptDesc.class);
        deptDesc.setId(deptDescs.get(0).getId());
        deptDescService.update(deptDesc);
        return ResultBuilder.success();
    }

    @ApiOperation("（测试数据）：科室介绍关联医生")
    @PostMapping(value = {"/relDeptDescDoctor"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（测试数据）：科室介绍关联医生")
    public Object relDeptDescDoctor(@Valid @RequestBody DeptDescDocRelAO deptDescDocRelAO) throws BizException {

        List<DeptDesc> deptDescs = deptDescService.findByDeptName(deptDescDocRelAO.getDeptDescName());
        if(CollectionUtils.isEmpty(deptDescs)){
            throw new BizException("90000002","科室介绍信息未匹配，请检查输入");
        }
        Doctor doctor = new Doctor();
        doctor.setName(deptDescDocRelAO.getDoctorName());
        if(!ObjectUtils.isEmpty(deptDescDocRelAO.getDoctorDept())){
            doctor.setMainDeptName(deptDescDocRelAO.getDoctorDept());
        }
        doctor.setStatus(CommonStatusEnum.INIT.getCode());
        List<Doctor> doctors = doctorService.select(doctor);
        if(CollectionUtils.isEmpty(doctors)){
            throw new BizException("90000002","医生信息未匹配，输入有误或his未录入该医生");
        }

        DeptDoctorDescRel rel = new DeptDoctorDescRel();
        rel.setDeptDescId(deptDescs.get(0).getId());
        rel.setDoctorId(doctors.get(0).getId());
        List<DeptDoctorDescRel> relList =
                deptDoctorDescRelService.findByDeptDescIdAndDoctorId(rel.getDeptDescId(), rel.getDoctorId());
        if(CollectionUtils.isEmpty(relList)){
            rel.setSort(deptDescDocRelAO.getDoctorSort());
            deptDoctorDescRelService.insert(rel);
        }else{
            DeptDoctorDescRel relUpdate = relList.get(0);
            relUpdate.setSort(deptDescDocRelAO.getDoctorSort());
            deptDoctorDescRelService.update(relUpdate);
        }
        //update doctor info
        Doctor params = doctors.get(0);
        if(!ObjectUtils.isEmpty(deptDescDocRelAO.getReusme())){
            params.setReusme(deptDescDocRelAO.getReusme());
        }
        if(!ObjectUtils.isEmpty(deptDescDocRelAO.getGoodAt())){
            params.setGoodAt(deptDescDocRelAO.getGoodAt());
        }
        if(!ObjectUtils.isEmpty(deptDescDocRelAO.getDescription())){
            params.setDescription(deptDescDocRelAO.getDescription());
        }
        if(!ObjectUtils.isEmpty(deptDescDocRelAO.getHeadPhoto())){
            params.setHeadPhoto(deptDescDocRelAO.getHeadPhoto());
        }
        doctorService.update(params);

        return ResultBuilder.success();
    }

    @ApiOperation("（测试数据）：医生信息更新")
    @PostMapping(value = {"/updateDoctor"})
    @Log(source = LogSourceEnum.APP, type = LogTypeEnum.SELECT, desc = "（测试数据）：医生信息更新")
    public Object updateDoctor(@Valid @RequestBody TestDocUpdateAO testDocUpdateAO) throws BizException {

        Doctor doctor = new Doctor();
        doctor.setName(testDocUpdateAO.getDoctorName());
        if(!ObjectUtils.isEmpty(testDocUpdateAO.getDoctorDept())){
            doctor.setMainDeptName(testDocUpdateAO.getDoctorDept());
        }
        doctor.setStatus(CommonStatusEnum.INIT.getCode());
        List<Doctor> doctors = doctorService.select(doctor);
        if(CollectionUtils.isEmpty(doctors)){
            throw new BizException("90000002","医生信息未匹配，输入有误或his未录入该医生");
        }
        if(doctors.size() > 1){
            throw new BizException("90000002","医生信息存在多个，请增加部门条件更新~");
        }
        //update doctor info
        Doctor params = doctors.get(0);
        if(!ObjectUtils.isEmpty(testDocUpdateAO.getReusme())){
            params.setReusme(testDocUpdateAO.getReusme());
        }
        if(!ObjectUtils.isEmpty(testDocUpdateAO.getGoodAt())){
            params.setGoodAt(testDocUpdateAO.getGoodAt());
        }
        if(!ObjectUtils.isEmpty(testDocUpdateAO.getDescription())){
            params.setDescription(testDocUpdateAO.getDescription());
        }
        if(!ObjectUtils.isEmpty(testDocUpdateAO.getHeadPhoto())){
            params.setHeadPhoto(testDocUpdateAO.getHeadPhoto());
        }
        doctorService.update(params);

        return ResultBuilder.success();
    }

}

